package archer.framework.common.entity.validate;


import archer.framework.utils.ValidateUtils;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.*;

/**
 * @author Kent
 * @date 2015/7/7.
 */
public class BeanValidators {

    private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * bean校验
     *
     * @param bean
     * @return
     */
    public static ValidateResult entityValidate(Object bean) {
        if (bean != null) {
            try {
                BeanValidators.validateWithException(validator, bean);
            } catch (ConstraintViolationException e) {
                // 校验不通过
                return ValidateResult.failInstance(BeanValidators.extractMessage(e));
            }
        }

        // 校验成功
        return ValidateResult.successInstance();
    }

    /**
     * bean校验
     *
     * @param bean
     * @return
     */
    public static ValidateResult entityValidate(List<Object> bean) {

        if (ValidateUtils.isEmpty(bean)) {
            return ValidateResult.successInstance();
        }

        ValidateResult validateResult = ValidateResult.successInstance();

        for (Object each : bean) {
            ValidateResult eachResult = entityValidate(each);

            if (eachResult.fail()) {
                validateResult.setSuccess(false).addErrors(eachResult.errors());
            }
        }
        return validateResult;
    }


    /**
     * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException, 而不是返回constraintViolations.
     */
    public static void validateWithException(Validator validator, Object object, Class<?>... groups)
            throws ConstraintViolationException {
        Set constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            throw new ConstraintViolationException(constraintViolations);
        }
    }


    /**
     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>.
     */
    public static List<String> extractMessage(ConstraintViolationException e) {
        return extractMessage(e.getConstraintViolations());
    }

    /**
     * 辅助方法, 转换Set<ConstraintViolation>为List<message>
     */
    public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
        List<String> errorMessages = new ArrayList<String>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.add(violation.getMessage());
        }
        return errorMessages;
    }


    /**
     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>.
     */
    public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
        return extractPropertyAndMessage(e.getConstraintViolations());
    }

    /**
     * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.
     */
    public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
        Map<String, String> errorMessages = new HashMap<String, String>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
        }
        return errorMessages;
    }
}
